package com.jswdwsx.esign.service

import com.jswdwsx.esign.cloud.enums.SealTypeEnum
import com.jswdwsx.esign.commom.ResEnum
import com.jswdwsx.esign.entity.OrgPO
import com.jswdwsx.esign.entity.SealPO
import com.jswdwsx.esign.entity.UserPO
import com.jswdwsx.esign.exception.EsignBusinessException
import com.jswdwsx.esign.protocol.EsignApi
import com.jswdwsx.esign.protocol.request.OrgReq
import com.jswdwsx.esign.protocol.request.OrgSealReq
import com.jswdwsx.esign.protocol.request.UpdateOrgReq
import com.jswdwsx.esign.protocol.response.QueryOrgResp
import com.jswdwsx.esign.protocol.response.QueryOrgSealResp
import com.jswdwsx.esign.repo.OrgRepository
import com.jswdwsx.esign.repo.SealRepository
import com.jswdwsx.esign.service.dto.CreateAccountDTO
import com.jswdwsx.esign.util.Id
import org.slf4j.LoggerFactory.getLogger
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import java.util.*


@Service
class OrganizationService(
    private val orgRepository: OrgRepository,
    private val sealRepository: SealRepository,
    private val esignApi: EsignApi
) {

    private val logger = getLogger(OrganizationService::class.java)

    fun queryOrg(orgId: String): QueryOrgResp {
        val esignResp = esignApi.queryOrganization(orgId)
        logger.info("查询机构账号响应：$esignResp")
        return esignResp.data(ResEnum.CallEsignUserQueryFail)
    }

    /**
     * 根据企业证件号和证件类型查找是否已存在企业，有就直接返回，没有就创建了返回
     */
    fun checkAndCreateOrg(signer: UserPO, createAccountDTO: CreateAccountDTO): OrgPO {
        val orgIdType = createAccountDTO.orgIdType
        val orgIdNumber = createAccountDTO.orgIdNumber
        val orgName = createAccountDTO.orgName

        if (orgIdType == null || orgIdNumber == null || orgName == null) {
            throw EsignBusinessException(ResEnum.OrgInfoRequired)
        }
        val orgList = orgRepository.findAllByIdTypeAndIdNumber(orgIdType, orgIdNumber)
        if (orgList.isNotEmpty()) {
            return orgList[0]
        }
        return createOrg(
            OrgReq(
                thirdPartyUserId = "${Id.ORG.prefix}${UUID.randomUUID()}",
                name = orgName,
                creator = signer.accountId,
                idType = createAccountDTO.orgIdType,
                idNumber = createAccountDTO.orgIdNumber
            )
        )
    }

    fun createOrg(orgReq: OrgReq): OrgPO {
        val esignResp = esignApi.createOrganization(orgReq = orgReq)
        logger.info("创建企业接口响应：${esignResp}")
        val orgResp = esignResp.data(ResEnum.CallEsignOrgCreateFail)
        return orgRepository.save(
            OrgPO(
                orgReq.thirdPartyUserId,
                orgReq.name,
                orgResp.orgId,
                orgReq.idType,
                orgReq.idNumber,
                orgReq.creator
            )
        )
    }

    /**
     * 更新企业信息
     */
    fun updateOrganization(orgId: String, updateOrgReq: UpdateOrgReq): OrgPO? {
        val orgPO = orgRepository.findByIdOrNull(orgId) ?: throw EsignBusinessException(ResEnum.OrgDoesNotExist)

        val esignResp = esignApi.updateOrganization(
            orgId = orgPO.esignOrgId,
            updateOrgReq = updateOrgReq
        )
        logger.info("更新企业接口响应：${esignResp}")

        val orgResp = esignResp.data(ResEnum.CallEsignOrgUpdateFail)
        orgPO.name = orgResp.name
        orgPO.idType = orgResp.idType
        orgPO.idNumber = updateOrgReq.idNumber
        orgPO.orgLegalIdNumber = orgResp.orgLegalIdNumber
        orgPO.orgLegalName = orgResp.orgLegalName

        return orgRepository.save(orgPO)
    }

    fun checkAndCreateDefaultOrgSeal(org: OrgPO): SealPO {

        return sealRepository.findByOwnerAndName(org.esignOrgId, DEFAULT_SEAL_NAME)
            ?: createTemplateSeal(
                org.esignOrgId, OrgSealReq(
                    alias = DEFAULT_SEAL_NAME,
                    central = "STAR",
                    color = "RED",
                    htext = "合同章",
                    type = "TEMPLATE_ROUND"
                )
            )
    }

    fun createTemplateSeal(orgId: String, orgSealReq: OrgSealReq): SealPO {
        logger.info("创建组织印章请求参数：${orgSealReq}")
        val esignResp = esignApi.createOrgSeal(orgId, orgSealReq)
        logger.info("创建组织印章响应参数：${esignResp}")
        val sealResp = esignResp.data(ResEnum.CallEsignOrgSealCreateFail)
        return sealRepository.save(
            SealPO(
                esignSealId = sealResp.sealId!!,
                fileKey = sealResp.fileKey,
                owner = orgId,
                type = SealTypeEnum.ORG,
                name = orgSealReq.alias
            )
        )
    }

    fun queryOrgSeals(orgId: String): QueryOrgSealResp? {
        return esignApi.getOrgSeals(orgId).data
    }

    companion object {
        private const val DEFAULT_SEAL_NAME = "企业默认星型印章"
    }
}
